package com.cancer.common.web;

import java.util.HashMap;
import java.util.Map;
import com.cancer.common.web.Sort.Order;

/**
 * 将当前分页请求信息保存到线程变量中
 * 
 * @company GeekPlus
 * @project beetle
 * @author 刘俊
 * @date 2016年4月13日
 * @since 1.0.0
 */
public class PagingContext {

	/** 分页的起始页 **/
	private final static ThreadLocal<Integer> _pageNo = new ThreadLocal<Integer>();

	/** 页偏移 **/
	private final static ThreadLocal<Integer> _pageOffset = new ThreadLocal<Integer>();

	/** 分页大小 **/
	private final static ThreadLocal<Integer> _pageSize = new ThreadLocal<Integer>();

	/** 排序信息 **/
	private final static ThreadLocal<Sort> _sort = new ThreadLocal<Sort>();

	public static Integer getPageSize() {
		return _pageSize.get();
	}

	/**
	 * 若pageSize为null，则返回指定的默认值
	 * 
	 * @author 刘俊 2016年4月15日
	 * @param defaultSize
	 * @return
	 */
	public static Integer getPageSize(int defaultSize) {
		return _pageSize.get() == null ? defaultSize : _pageSize.get();
	}

	public static void setPageSize(int pageSize) {
		_pageSize.set(pageSize);
	}

	public static void removePageSize() {
		_pageSize.remove();
	}

	public static Integer getPageNo() {
		return _pageNo.get();
	}

	public static void setPageNo(int pageNo) {
		_pageNo.set(pageNo);
	}

	public static void removePageNo() {
		_pageNo.remove();
	}

	public static Integer getPageOffset() {
		return calcOffset();
	}

	public static void setPageOffset(int pageOffset) {
		_pageOffset.set(pageOffset);
	}

	public static void removePageOffset() {
		_pageOffset.remove();
	}

	public static Sort getSort() {
		return _sort.get();
	}

	public static void setSort(Sort sort) {
		_sort.set(sort);
	}

	/**
	 * 设置当前页面
	 * 
	 * @author 刘俊 2016年4月13日
	 * @param pageNo
	 * @param pageSize
	 */
	public static void setNoAndSize(Integer pageNo, Integer pageSize) {
		_pageNo.set(pageNo);
		_pageSize.set(pageSize);
	}

	/**
	 * 设置当前页面
	 * 
	 * @author 刘俊 2016年4月13日
	 * @param pageNo
	 * @param pageSize
	 */
	public static void setOffsetAndSize(Integer pageNo, Integer pageSize) {
		_pageNo.set(pageNo);
		_pageSize.set(pageSize);
	}

	/**
	 * 添加排序项
	 * 
	 * @autohr 刘俊 2016年2月25日
	 * @param order
	 */
	public static void addSortItem(Order order) {
		Sort sort = _sort.get();
		if (sort == null) {
			sort = new Sort(order);
			_sort.set(sort);
		} else {
			sort.add(order);
		}
	}

	/**
	 * 移除所有线程变量
	 * 
	 * @author 刘俊 2016年4月13日
	 */
	public static void removeAll() {
		_sort.remove();
		_pageNo.remove();
		_pageSize.remove();
		_pageOffset.remove();
	}

	/**
	 * <pre>
	 * 根据线程变量中的值计算起始记录位置
	 * 计算方法：
	 * 1. 如果pageOffset有值（但并不检查合法性），直接返回offset
	 * 2. 如果pageOffset为null，则根据pageNo和pageSize计算出offset，若pageNo或pageSize为空或不正确则返回0。
	 * </pre>
	 * @author 刘俊 2016年4月15日
	 * @return
	 */
	public static int calcOffset() {
		Integer pageOffset = _pageOffset.get();
		if (pageOffset == null) {
			Integer pageNo = _pageNo.get();
			if (pageNo == null || pageNo < 1) {
				return 0;
			} else {
				Integer pageSize = _pageSize.get() == null ? 0 : _pageSize.get();
				return (pageNo - 1) * pageSize;
			}
		} else {
			return pageOffset;
		}
	}
	
	/**
	 * <pre>
	 * 根据线程变量中的值计算起始记录位置
	 * 计算方法：
	 * 1. 如果pageOffset有值（但并不检查合法性），直接返回offset
	 * 2. 如果pageOffset为null，则根据pageNo和pageSize计算出offset。
	 * （若pageNo的值不合法为null或小于1，则返回0，pageSize的值不合法为null或小于1，则初始化为15）
	 * </pre>
	 * @author 刘俊 2016年4月15日
	 * @param defSize	指定默认的页大小
	 * @return
	 */
	public static int calcOffset(int defSize) {
		Integer pageOffset = _pageOffset.get();
		if (pageOffset == null) {
			Integer pageNo = _pageNo.get();
			if (pageNo == null || pageNo < 1) {
				return 0;
			} else {
				Integer pageSize = _pageSize.get() == null ? defSize : _pageSize.get();
				return (pageNo - 1) * pageSize;
			}
		} else {
			return pageOffset;
		}
	}
	
	/**
	 * 将参数转为map
	 * 
	 * @author 刘俊 2016年4月15日
	 * @return
	 */
	public static Map<String, Object> asMap() {
		Map<String, Object> params = new HashMap<>();
		params.put("currentPage", _pageNo.get());
		params.put("pageSize", _pageSize.get());
		params.put("pageOffset", calcOffset());
		params.put("orders", _sort.get() == null ? null : _sort.get().getOrders());
		
		return params;
	}
}
